from flask import Blueprint, jsonify, current_app, request
from sqlalchemy import asc

from models import Clazz, Teacher, db, Student  # 假设 Clazz, Teacher 是模型，db 是数据库实例
from sqlalchemy.exc import IntegrityError

api_bp = Blueprint('class', __name__)


# 1. 获取班级列表
@api_bp.route('/classes', methods=['GET'])
def get_classes():
    try:
        page = request.args.get('page', 1, type=int)
        page_size = request.args.get('page_size', 10, type=int)
        page_size = min(max(page_size, 1), 100)

        # 关键词查询参数
        keyword = request.args.get('kw', '').strip()

        # 构建基础查询
        query = Clazz.query.join(
            Teacher, Clazz.head_teacher_id == Teacher.id, isouter=True
        ).add_columns(
            Clazz.id,
            Clazz.classId,
            Clazz.name,
            Clazz.grade,
            Clazz.major,
            Clazz.head_teacher_id,
            Teacher.name.label('head_teacher_name')
        ).order_by(asc(Clazz.classId))

        # 添加关键词查询条件
        if keyword:
            keyword = f'%{keyword}%'  # 模糊查询
            query = query.filter(
                (Clazz.name.ilike(keyword)) |
                (Clazz.grade.ilike(keyword))
            )

        # 查询总记录数（带关键词条件）
        total_items = query.count()

        # 计算总页数
        total_pages = (total_items + page_size - 1) // page_size
        page = max(1, min(page, total_pages))  # 防止页码越界

        # 执行分页查询
        classes = query.offset((page - 1) * page_size).limit(page_size).all()

        data = []
        for clazz in classes:

            data.append({
                "id": clazz.id,
                "class_id": clazz.classId,
                "name": clazz.name,
                "grade": clazz.grade,
                "major": clazz.major,
                "head_teacher_id": clazz.head_teacher_id,
                "head_teacher_name": clazz.head_teacher_name,
                "students": [{
                    "id": student.id,
                    "student_id": student.studentId,
                    "name": student.name,
                    "gender": student.gender,
                    "phone": student.phone,
                } for student in Student.query.filter(Student.class_id == clazz.id).all()]
            })

        return jsonify({
            "message": "获取班级列表成功",
            "data": data,
            "pagination": {
                "current_page": page,
                "page_size": page_size,
                "total_pages": total_pages,
                "total_items": total_items
            }
        }), 200

    except Exception as e:
        current_app.logger.error(f"获取班级列表失败: {str(e)}", exc_info=True)
        return jsonify({"message": "获取班级列表失败"}), 500


# 2. 添加班级
@api_bp.route('/classes', methods=['POST'])
def add_class():
    try:
        data = request.json
        required_fields = ["class_id", "name", "grade", "major", "head_teacher_id"]
        for field in required_fields:
            if field not in data:
                return jsonify({"message": f"缺少必要参数: {field}"}), 400

        # 验证班主任是否存在
        teacher = Teacher.query.get(data["head_teacher_id"])
        if not teacher:
            return jsonify({"message": "班主任不存在"}), 400

        # 检查班级编号是否已存在
        existing_class = Clazz.query.filter(Clazz.classId == data["class_id"]).first()
        if existing_class:
            return jsonify({"message": "班级编号已存在"}), 400

        new_class = Clazz(
            classId=data["class_id"],
            name=data["name"],
            grade=data["grade"],
            major=data["major"],
            head_teacher_id=data["head_teacher_id"]
        )
        db.session.add(new_class)
        db.session.commit()
        return jsonify({
            "message": "班级添加成功",
            "class_id": new_class.id
        }), 201

    except IntegrityError:
        db.session.rollback()
        current_app.logger.error("数据库操作冲突")
        return jsonify({"message": "添加班级失败"}), 500
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"添加班级失败: {str(e)}", exc_info=True)
        return jsonify({"message": "添加班级失败"}), 500


# 3. 更新班级信息
@api_bp.route('/classes/<int:class_id>', methods=['PUT'])
def update_class(class_id):
    try:
        data = request.json
        clazz = Clazz.query.get(class_id)

        if not clazz:
            return jsonify({"message": "班级记录不存在"}), 404

        # 验证班主任是否存在（如果更新了班主任ID）
        if "head_teacher_id" in data:
            teacher = Teacher.query.get(data["head_teacher_id"])
            if not teacher:
                return jsonify({"message": "班主任不存在"}), 400

        # 检查新的班级编号是否已存在（如果更新了班级编号）
        if "class_id" in data and data["class_id"] != clazz.classId:
            existing_class = Clazz.query.filter(Clazz.classId == data["class_id"]).first()
            if existing_class:
                return jsonify({"message": "班级编号已存在"}), 400

        # 更新班级信息
        if "class_id" in data:
            clazz.classId = data["class_id"]
        if "name" in data:
            clazz.name = data["name"]
        if "grade" in data:
            clazz.grade = data["grade"]
        if "major" in data:
            clazz.major = data["major"]
        if "head_teacher_id" in data:
            clazz.head_teacher_id = data["head_teacher_id"]

        db.session.commit()

        return jsonify({
            "message": "班级信息更新成功",
            "class_id": clazz.id
        }), 200

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"更新班级信息失败: {str(e)}", exc_info=True)
        return jsonify({"message": "更新班级信息失败"}), 500


# 4. 删除班级
@api_bp.route('/classes/<int:class_id>', methods=['DELETE'])
def delete_class(class_id):
    try:
        clazz = Clazz.query.get(class_id)

        if not clazz:
            return jsonify({"message": "班级记录不存在"}), 404

        # 检查是否有学生属于该班级
        if clazz.students:
            return jsonify({"message": "该班级下有学生，无法删除"}), 400

        db.session.delete(clazz)
        db.session.commit()

        return jsonify({"message": "班级已删除"}), 200

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"删除班级失败: {str(e)}", exc_info=True)
        return jsonify({"message": "删除班级失败"}), 500
